const fs = require('fs').promises;  // 引入Node.js的文件系统模块，使用Promise API
const path = require('path');       // 引入Node.js的路径模块

/**
 * 文件扫描器类，用于扫描指定目录中的文件夹，提取符合指定格式的代码（如RJ, BJ, VJ编号），并检测特定关键字。
 */
class FileScanner {
    /**
     * 构造函数，初始化根目录路径。
     * 
     * @param {string} rootDir - 要扫描的根目录路径
     */
    constructor(rootDir) {
        this.rootDir = rootDir;
    }

    /**
     * 扫描根目录，并返回符合条件的文件夹信息。
     * 
     * @returns {Promise<Array>} - 返回包含文件夹代码、路径及关键字检测结果的数组
     */
    async scan() {
        const results = [];
        await this.scanDirectory(this.rootDir, results);
        return results;
    }

    /**
     * 扫描指定目录，提取包含特定关键字的文件夹名称及代码信息。
     * 
     * @param {string} dir - 要扫描的目录路径
     * @param {Array} results - 保存扫描结果的数组
     * @returns {Promise<void>} - 返回一个Promise，当目录扫描完成时解决
     */
    async scanDirectory(dir, results) {
        const entries = await fs.readdir(dir, { withFileTypes: true });  // 读取目录内容

        for (const entry of entries) {
            const fullPath = path.join(dir, entry.name);  // 获取当前条目的完整路径

            if (entry.isDirectory()) {  // 只处理文件夹
                const code = this.extractCode(entry.name);  // 从文件夹名称中提取RJ、BJ、VJ编号
                const subtitlePresent = this.checkForSubtitle(entry.name);  // 检查是否包含“字幕”
                const vr = this.checkForVR(entry.name);  // 检查是否包含“VR”
                const languageKeyword = this.checkForLanguageKeyword(entry.name);  // 检查是否包含语言相关关键字

                // 将扫描结果存入数组
                results.push({
                    folderName: entry.name,
                    path: fullPath,
                    code: code,              // 提取到的RJ、BJ、VJ编号，可能为null
                    isSub: subtitlePresent,  // 如果包含“字幕”，则为true，否则为false
                    isVR: vr,                // 如果包含“VR”，则为true，否则为false
                    lang: languageKeyword    // 如果包含语言关键字，则为该关键字，否则为null
                });
            }
        }
    }

    /**
     * 从文件夹名称中提取符合格式的代码（如RJ, BJ, VJ编号）。
     * 
     * @param {string} folderName - 当前文件夹名称
     * @returns {string|null} - 返回提取的代码，如果不匹配则返回null
     */
    extractCode(folderName) {
        const match = folderName.match(/([RVB]J\d+)/i);  // 使用正则表达式匹配RJ、BJ或VJ编号
        return match ? match[1].toUpperCase() : null;    // 如果匹配成功，将其转换为大写返回，否则返回null
    }

    /**
     * 检查文件夹名称是否包含“字幕”。
     * 
     * @param {string} folderName - 当前文件夹名称
     * @returns {boolean} - 如果包含“字幕”返回true，否则返回false
     */
    checkForSubtitle(folderName) {
        return folderName.includes('字幕');  // 判断文件夹名称中是否包含“字幕”
    }

    /**
     * 检查文件夹名称是否包含“VR”。
     * 
     * @param {string} folderName - 当前文件夹名称
     * @returns {boolean} - 如果包含“VR”返回true，否则返回false
     */
    checkForVR(folderName) {
        return folderName.includes('VR');  // 判断文件夹名称中是否包含“VR”
    }

    /**
     * 检查文件夹名称是否包含“汉化”、“中文”、“EN”、“双语”中的任意一个关键字。
     * 
     * @param {string} folderName - 当前文件夹名称
     * @returns {string|null} - 返回匹配的关键字，如果没有匹配则返回null
     */
    checkForLanguageKeyword(folderName) {
        const keywords = ['汉化', '中文', 'EN', '双语'];  // 定义要检查的语言关键字
        for (const keyword of keywords) {
            if (folderName.includes(keyword)) {
                return keyword;  // 如果找到匹配的关键字，则返回
            }
        }
        return null;  // 如果没有匹配，返回null
    }
}

module.exports = FileScanner;  // 导出FileScanner类
